package org.fight.manager;

import java.util.ArrayList;
import java.util.List;

import org.fight.bean.AbstractFight;
import org.fight.bean.AbstractFight.NetFrame;
import org.fight.bean.AbstractFight.OperateFrame;
import org.fight.bean.FightStatusEnum;
import org.fight.bean.TestFight;
import org.fight.cache.FightCache;
import org.fight.cache.FightPlayerCache;
import org.fight.logic.fightbo.FightBO;
import org.fight.logic.fightbo.FightPlayer;
import org.fight.net.KcpConstant;
import org.fight.protobuf.C2SFightMsg.ReqOperateFight;
import org.fight.protobuf.S2CFightMsg;
import org.fight.protobuf.S2CFightMsg.NotifyNetFrame;
import org.fight.protobuf.S2CFightMsg.NotifyStartFight;

import com.sojoys.artifact.factory.message.IMessage;
import com.sojoys.artifact.manager.MessageManager;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.date.TimeInterval;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.LogFactory;

/**
 * @author : DengYing
 * @CreateDate : 2018年2月28日 下午6:10:02
 * @Description ：战斗管理器
 */
public class FightManager {
	
	static final Log log = LogFactory.get(FightManager.class);
	
	private FightManager() {
	}

	private static FightManager ME = new FightManager();

	public static FightManager me() {
		return ME;
	}

	/** 创建战斗 */
	public AbstractFight createFight(String fightId) {
		AbstractFight fight = new TestFight(fightId, 1);
		FightCache.put(fight);
		return fight;
	}

	/** 进入战斗 */
	public void enterFight(AbstractFight fight, FightPlayer fightPlayer) {
		List<FightPlayer> fightPlayers = fight.getFightPlayers();
		fightPlayers.add(fightPlayer);

		if (fightPlayers.size() >= fight.getNeedFightPlayerCount()) {
			fight.setStatus(FightStatusEnum.RUNING);

			// 发送开始消息
			IMessage msg = MessageManager.me().create(FightBO.startFight,NotifyStartFight.newBuilder().build().toByteArray());
			for (FightPlayer player : fightPlayers) {
				player.sendMsg(msg);
			}
		}
	}

	/** 销毁战斗 */
	public void destroyFight(AbstractFight fight) {
		List<FightPlayer> fightPlayers = fight.getFightPlayers();
		for (FightPlayer fightPlayer : fightPlayers) {
			FightPlayerCache.remove(fightPlayer.getPid());
			// 关闭Session
//			fightPlayer.getSession().close();
			// 清除缓存
//			SessionCache.me().remove(fightPlayer.getSession().getAttr(KcpConstant.CONV));
		}
		// 移除战斗
		FightCache.remove(fight.getFightId());
		log.info("-> destroyFight fightId : {}" + fight.getFightId());
	}

	/** 操作战斗 */
	public void operate(FightPlayer fightPlayer, AbstractFight fgiht, ReqOperateFight operate) {

		NetFrame currentFrame = fgiht.getCurrentFrame();

		List<OperateFrame> operateFrame = currentFrame.getOperateFrame();
		operateFrame.add(new OperateFrame(fightPlayer.getPid(),operate.getKeyCode(), operate.getKeyEvent()));	
	}
	StringBuffer sb = new StringBuffer();
	/** 通知当前帧 */
//	TimeInterval timer = DateUtil.timer();
	public void notifyCurrentFrame(AbstractFight fgiht) {
		List<FightPlayer> fightPlayers = fgiht.getFightPlayers();
		// 取得当前帧
		NetFrame netFrame = fgiht.getCurrentFrame();
		S2CFightMsg.NetFrame netFrameMsg = buildNetFrameMsg(netFrame);
		// 跟换当前帧
		fgiht.setCurrentFrame(new NetFrame(netFrame.getIndex()+1));
		
		IMessage msg = MessageManager.me().create(FightBO.notifyNetFrame,NotifyNetFrame.newBuilder().setNetFrame(netFrameMsg).build().toByteArray());
		// 发送网络帧消息
//		sb.setLength(0);
		for (FightPlayer player : fightPlayers) {
			player.sendMsg(msg);
//			sb.append(player.getSession().getAttr(KcpConstant.TARGET_ADDRESS).toString());
		}
//		System.out.println(sb.toString() + " " + timer.interval());
//		timer.restart();
	}

	/**
	 * 拉取帧集
	 * 
	 * @return
	 */
	public List<NetFrame> pullNetFrame(AbstractFight fgiht, int fromIndex) {
		int toIndex = fgiht.getNetFrames().size();
		return fgiht.getNetFrames().subList(fromIndex, toIndex);
	}

	/**
	 * 构建网络帧消息
	 * 
	 * @param netFrame
	 * @return
	 */
	public S2CFightMsg.NetFrame buildNetFrameMsg(NetFrame netFrame) {
		List<OperateFrame> operateFrames = netFrame.getOperateFrame();
		S2CFightMsg.NetFrame.Builder netFrameBuilder = S2CFightMsg.NetFrame.newBuilder();
		netFrameBuilder.setIndex(netFrame.getIndex());
		operateFrames.forEach((v) -> {
			S2CFightMsg.OperateFrame.Builder operateFrameBuilder = S2CFightMsg.OperateFrame.newBuilder();
			operateFrameBuilder.setPid(v.getPid());
			operateFrameBuilder.setKeyCode(v.getKeyCode());
			operateFrameBuilder.setKeyEvent(v.getKeyEvent());
			netFrameBuilder.addOperateFrame(operateFrameBuilder);
		});
		return netFrameBuilder.build();
	}
	
	/**
	 * 构建网络帧消息
	 * 
	 * @param netFrame
	 * @return
	 */
	public List<S2CFightMsg.NetFrame> buildNetFramesMsg(List<NetFrame> netFrames) {
		List<S2CFightMsg.NetFrame> list = new ArrayList<>(netFrames.size());
		for (NetFrame netFrame : netFrames) {
			list.add(buildNetFrameMsg(netFrame));
		}
		return list;
	}
}
